home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1991 / 02 / file.asm < prev    next >
Assembly Source File  |  1990-10-31  |  5KB  |  257 lines

  1.     title    file i/o for block storage
  2.     include    asm.inc
  3.  
  4.     public    check_block_file
  5.     public    open_block_file
  6.     public    read_block_file
  7.     public    set_block_handle
  8.  
  9.  
  10. NULL_HANDLE    equ    0
  11. NULL_ID        equ    0
  12.  
  13.  
  14. file_str struc
  15.   f_next    dd    ?
  16.   f_size    dd    ?
  17.   f_index    dw    ?        ; block index
  18.   f_id        dw    ?
  19. file_str ends
  20. f_name        equ    (size file_str)
  21.  
  22.  
  23.     .data?
  24. file_list        dd    ?
  25. file_end        dd    ?
  26. file_count        dw    ?
  27.  
  28. current_id        dw    ?
  29. current_handle        dw    ?
  30.  
  31.  
  32.     .const
  33. ertx_file_id        db    'Bad file id',0
  34. ertx_file_missing    db    'File missing',0
  35. ertx_too_big        db    'File too big',0
  36.  
  37.  
  38.     .code
  39.  extn move_file_pointer,set_strerror,read_from_file,open_input_file,save_most
  40.  extn close_file,strcmpi,input_file_size,strlenz,calloc,strcpy
  41.  
  42.  
  43. ;;    change current file
  44. ;
  45. ;    entry    DX    file id
  46. ;    exit    Cf    if file not found
  47. ;    uses    SI,DS
  48. ;
  49. change_current_file proc
  50.     pushm    ax,bx
  51.     mov    current_id[bp],NULL_ID
  52.  
  53.     movx    bx,NULL_HANDLE        ; close current file
  54.     xchg    bx,current_handle[bp]
  55.     cmpx    bx,NULL_HANDLE
  56.     je    ccf1            ;  if no file open
  57.     call    close_file
  58.  
  59. ccf1:    lds    si,file_list[bp]
  60.     jmp    ccf3
  61.  
  62. ccf2:    lds    si,f_next[si]        ; search file structures
  63. ccf3:    mov    ax,ds
  64.     or    ax,si
  65.     je    ccf5            ;  if file id not found
  66.     cmp    dx,f_id[si]
  67.     jne    ccf2            ;  if wrong file, keep searching
  68.  
  69.     lea    si,f_name[si]        ; open file
  70.     call    open_input_file
  71.     jc    ccf5
  72.  
  73.     mov    current_handle[bp],bx    ; set handle and file id
  74.     mov    current_id[bp],dx
  75.  
  76. ccf4:    popm    bx,ax
  77.     ret
  78.  
  79. ccf5:    lea    ax,ertx_file_missing    ; *File missing*
  80.     call    set_strerror
  81.     jmp    ccf4
  82. change_current_file endp
  83.  
  84.  
  85. ;;    check block file
  86. ;
  87. ;    entry    DS:SI    file name
  88. ;    exit    BX    file id or 0 if unknown file
  89. ;
  90. check_block_file proc
  91.     pushm    di,es
  92.     les    di,file_list[bp]
  93.     jmp    cbf2
  94.  
  95. cbf1:    les    di,es:f_next[di]
  96. cbf2:    mov    bx,es
  97.     or    bx,di
  98.     stc
  99.     jz    cbf3            ;  if file not found
  100.     push    di
  101.     lea    di,f_name[di]
  102.     call    strcmpi
  103.     pop    di
  104.     jne    cbf1            ;  if wrong file
  105.     mov    bx,es:f_id[di]
  106.     clc
  107.  
  108. cbf3:    popm    es,di
  109.     ret
  110. check_block_file endp
  111.  
  112.  
  113. ;;    current file size
  114. ;
  115. ;    exit    CX    file size in 16k blocks
  116. ;        Cf    if unexpected error
  117. ;    uses    AX
  118. ;
  119. current_file_size proc
  120.     pushm    bx,dx
  121.     mov    bx,current_handle[bp]
  122.     call    input_file_size
  123.     jc    cfs1            ;  if unexpected error
  124.  
  125.     mov    cx,BLOCK_SIZE        ; divide file size by 16k to get
  126.     cmp    dx,cx            ;  block count
  127.     jae    cfs2            ;   if too many 16k blocks
  128.     div    cx
  129.  
  130.     add    dx,-1            ; adjust count for partial block
  131.     adc    ax,ZER0
  132.     mov    cx,ax
  133.  
  134. cfs1:    popm    dx,bx
  135.     ret
  136.  
  137. cfs2:    lea    ax,ertx_too_big        ; *File too big*
  138.     call    set_strerror
  139.     jmp    cfs1
  140. current_file_size endp
  141.  
  142.  
  143. ;;    link new file
  144. ;
  145. ;    entry    ES:DI    file structure
  146. ;    exit    AX    file structure count
  147. ;
  148. link_new_file proc
  149.     inc    file_count[bp]
  150.     mov    ax,file_count[bp]
  151.     cmp    ax,1
  152.     je    lnf1            ;  if first file structure
  153.  
  154.     pushm    si,ds            ;  else add new file structure to
  155.     lds    si,file_end[bp]        ;   the end of the list
  156.     mov    wptr f_next[si],di
  157.     mov    wptr f_next[si+2],es
  158.     popm    ds,si
  159.     jmp    lnf2
  160.  
  161. lnf1:    mov    wptr file_list[bp],di    ; set 1st entry in file structure list
  162.     mov    wptr file_list[bp+2],es
  163.  
  164. lnf2:    mov    wptr file_end[bp],di    ; set end of file structure list
  165.     mov    wptr file_end[bp+2],es
  166.     ret
  167. link_new_file endp
  168.  
  169.  
  170. ;;    open block file
  171. ;
  172. ;    entry    DS:SI    file name
  173. ;    exit    CX    file size in 16k blocks
  174. ;        DX    file id (1..n)
  175. ;        Cf    if file not found or no storage
  176. ;    uses    AX
  177. ;
  178. open_block_file proc
  179.     pushm    bx,di,si,ds,es
  180.     call    strlenz            ; allocate file structure
  181.     add    cx,size file_str
  182.     call    calloc
  183.     jc    obf1            ;  if no memory
  184.  
  185.     call    link_new_file        ; link file struct to end of file list
  186.     mov    dx,ax
  187.     mov    es:f_id[di],ax
  188.  
  189.     lea    di,f_name[di]        ; copy file name into struct
  190.     call    strcpy
  191.  
  192.     call    change_current_file    ; close current file and open new file
  193.     jc    obf1            ;  if file not found
  194.  
  195.     call    current_file_size    ; get number of 16k blocks in file
  196.  
  197. obf1:    popm    es,ds,si,di,bx
  198.     ret
  199. open_block_file endp
  200.  
  201.  
  202. ;;    read block file
  203. ;
  204. ;    entry    AX    file block index (0..n)
  205. ;        BX    file id (1..n)
  206. ;        ES:DI    transfer address
  207. ;    exit    AX    byte count
  208. ;        Cf    if error
  209. ;
  210. read_block_file proc
  211.     call    save_most
  212.     cmp    bx,current_id[bp]
  213.     je    rbf1            ;  if file is already open
  214.  
  215.     mov    dx,bx            ;  else open file (new current file)
  216.     call    change_current_file
  217.     jc    rbf2            ;   if file missing or other error
  218.  
  219. rbf1:    mov    cx,BLOCK_SIZE        ; set file position
  220.     mul    cx
  221.     mov    bx,current_handle[bp]
  222.     call    move_file_pointer
  223.     jc    rbf2            ;  if unexpected error
  224.  
  225.     call    read_from_file        ; read block from file
  226. rbf2:    ret
  227. read_block_file endp
  228.  
  229.  
  230. ;;    set block handle
  231. ;
  232. ;    entry    BX    block handle
  233. ;        DX    file id
  234. ;    exit    Cf    if bad file id
  235. ;    uses    AX,CX,SI,DS
  236. ;
  237. set_block_handle proc
  238.     mov    cx,dx
  239.     jcxz    sbh3            ;  if bad file id
  240.  
  241.     lds    si,file_list[bp]    ; advance through file structure list
  242.     jmp    sbh2            ;  to selected entry
  243. sbh1:    lds    si,f_next[si]
  244. sbh2:    mov    ax,ds
  245.     or    ax,si            ;  (Cf=0)
  246.     jz    sbh3            ;  if bad file id
  247.     loop    sbh1
  248.  
  249.     mov    f_index[si],bx
  250.     ret
  251.  
  252. sbh3:    lea    ax,ertx_file_id        ; *Bad file id*
  253.     jmp    set_strerror
  254. set_block_handle endp
  255.  
  256.     end
  257.